home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 37
/
Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso
/
Aminet
/
dev
/
lang
/
sofa.lha
/
sofa
/
smalleiffel
/
lib_se
/
constant_pool.e
< prev
next >
Wrap
Text File
|
2000-03-25
|
15KB
|
628 lines
-- This file is part of SmallEiffel The GNU Eiffel Compiler.
-- Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
-- Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
-- http://SmallEiffel.loria.fr
-- SmallEiffel is free software; you can redistribute it and/or modify it
-- under the terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 2, or (at your option) any later
-- version. SmallEiffel is distributed in the hope that it will be useful,but
-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details. You should have received a copy of the GNU General
-- Public License along with SmallEiffel; see the file COPYING. If not,
-- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-- Boston, MA 02111-1307, USA.
--
class CONSTANT_POOL
--
-- Unique Global Object in charge of the CONSTANT_POOL
-- handling (the CONSTANT_POOL is an important part of a
-- JVM *.class file).
--
inherit CP_INFO_TAGS;
feature {NONE}
cp_up: INTEGER;
cp: FIXED_ARRAY[CP_INFO] is
-- Range [1.. `cp_up'] has no Void elements.
-- By the way, index 0 is not used and elements
-- are recycled.
once
!!Result.make(1);
end;
feature {PRINT_JVM_CLASS}
item(i: INTEGER): CP_INFO is
do
Result := cp.item(i);
end;
feature {PRINT_JVM_CLASS}
reset(new_upper: INTEGER) is
require
new_upper > 0
local
i: INTEGER;
do
from
cp_up := 0;
until
i = new_upper
loop
add_last.clear;
i := i + 1;
end;
ensure
cp_up = new_upper
end;
feature {JVM}
clear is
do
cp_up := 0;
-- Compute minimum standard idx :
idx_java_lang_object := idx_class2(fz_java_lang_object);
idx_jvm_root_class := idx_class2(jvm_root_class);
idx_constant_utf8 := idx_utf8("Code");
end;
write_bytes is
local
i: INTEGER;
do
echo.put_string("Constant pool: ");
echo.put_integer(cp_up);
echo.put_new_line;
jvm.b_put_u2(cp_up + 1);
from
i := 1;
until
i > cp_up
loop
cp.item(i).b_put;
i := i + 1;
end;
end;
feature -- Acces to some common idx :
idx_constant_utf8: INTEGER;
idx_java_lang_object: INTEGER;
idx_jvm_root_class: INTEGER;
feature
valid_index(idx: INTEGER): BOOLEAN is
do
Result := (1 <= idx) and then (idx <= cp_up);
end;
feature {PRINT_JVM_CLASS} -- Setting :
set_class(i: INTEGER; info: STRING) is
do
cp.item(i).set_class(info);
end;
set_fieldref(i: INTEGER; info: STRING) is
do
cp.item(i).set_fieldref(info);
end;
set_methodref(i: INTEGER; info: STRING) is
do
cp.item(i).set_methodref(info);
end;
set_interface_methodref(i: INTEGER; info: STRING) is
do
cp.item(i).set_interface_methodref(info);
end;
set_string(i: INTEGER; info: STRING) is
do
cp.item(i).set_string(info);
end;
set_integer(i: INTEGER; info: STRING) is
do
cp.item(i).set_integer(info);
end;
set_float(i: INTEGER; info: STRING) is
do
cp.item(i).set_float(info);
end;
set_long(i: INTEGER; info: STRING) is
do
cp.item(i).set_long(info);
end;
set_double(i: INTEGER; info: STRING) is
do
cp.item(i).set_double(info);
end;
set_name_and_type(i: INTEGER; info: STRING) is
do
cp.item(i).set_name_and_type(info);
end;
set_utf8(i: INTEGER; info: STRING) is
do
cp.item(i).set_utf8(info);
end;
feature -- Testing :
is_class(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_class;
end;
is_fieldref(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_fieldref;
end;
is_methodref(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_methodref;
end;
is_interface_methodref(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_interface_methodref;
end;
is_string(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_string;
end;
is_integer(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_integer;
end;
is_float(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_float;
end;
is_long(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_long;
end;
is_double(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_double;
end;
is_name_and_type(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_name_and_type;
end;
is_utf8(idx: INTEGER): BOOLEAN is
do
Result := cp.item(idx).is_utf8;
end;
feature -- Update and search :
idx_class2(name: STRING): INTEGER is
-- Where `name' can be fully qualified or unqualified.
local
utf8: INTEGER;
do
utf8 := idx_utf8(name);
from
Result := cp_up;
until
Result = 0 or else cp.item(Result).is_class_idx(utf8)
loop
Result := Result - 1;
end;
if Result = 0 then
tmp_info.clear;
tmp_info_append_u2(utf8);
add_last.set_class(tmp_info);
Result := cp_up;
end;
end;
idx_fieldref_for_manifest_string(key: STRING): INTEGER is
require
key /= Void
local
c, nt: INTEGER;
do
c := idx_class2(jvm_root_class);
nt := idx_name_and_type2(key,jvm_string_descriptor);
Result := idx_fieldref2(c,nt);
ensure
valid_index(Result)
end;
idx_fieldref(rf: RUN_FEATURE): INTEGER is
require
rf /= Void
local
c, nt: INTEGER;
do
c := rf.run_class.jvm_constant_pool_index;
nt := idx_name_and_type(rf);
Result := idx_fieldref2(c,nt);
ensure
valid_index(Result)
end;
idx_fieldref2(c, nt: INTEGER): INTEGER is
require
valid_index(c);
valid_index(nt)
do
from
Result := cp_up;
until
Result = 0 or else cp.item(Result).is_fieldref_idx(c,nt)
loop
Result := Result - 1;
end;
if Result = 0 then
tmp_info.clear;
tmp_info_append_u2(c);
tmp_info_append_u2(nt);
add_last.set_fieldref(tmp_info);
Result := cp_up;
end;
ensure
valid_index(Result)
end;
idx_fieldref3(class_name, field_name, descriptor: STRING): INTEGER is
-- Where `class_name' is the fully qualified name.
require
not class_name.is_empty;
not field_name.is_empty;
not descriptor.is_empty
local
c: INTEGER;
do
c := idx_class2(class_name);
Result := idx_fieldref4(c,field_name,descriptor);
end;
idx_fieldref4(c: INTEGER; field_name, descriptor: STRING): INTEGER is
local
nt: INTEGER;
do
nt := idx_name_and_type2(field_name,descriptor);
Result := idx_fieldref2(c,nt);
end;
idx_fieldref5(c, n, t: INTEGER): INTEGER is
local
nt: INTEGER;
do
nt := idx_name_and_type3(n,t);
Result := idx_fieldref2(c,nt);
end;
idx_methodref(rf: RUN_FEATURE): INTEGER is
require
rf /= Void
local
c, nt: INTEGER;
do
c := rf.run_class.jvm_constant_pool_index;
nt := idx_name_and_type(rf);
Result := idx_methodref2(c,nt);
ensure
valid_index(Result)
end;
idx_methodref1(c: INTEGER; method_name, descriptor: STRING): INTEGER is
require
valid_index(c);
not method_name.is_empty;
not descriptor.is_empty
local
nt: INTEGER;
do
nt := idx_name_and_type2(method_name,descriptor);
Result := idx_methodref2(c,nt);
end;
idx_methodref2(c, nt: INTEGER): INTEGER is
require
valid_index(c);
valid_index(nt)
do
from
Result := cp_up;
until
Result = 0 or else cp.item(Result).is_methodref_idx(c,nt)
loop
Result := Result - 1;
end;
if Result = 0 then
tmp_info.clear;
tmp_info_append_u2(c);
tmp_info_append_u2(nt);
add_last.set_methodref(tmp_info);
Result := cp_up;
end;
ensure
valid_index(Result)
end;
idx_methodref3(class_name, method_name, descriptor: STRING): INTEGER is
-- Where `class_name' is the fully qualified name.
require
not class_name.is_empty;
not method_name.is_empty;
not descriptor.is_empty
local
c: INTEGER;
do
c := idx_class2(class_name);
Result := idx_methodref1(c,method_name,descriptor);
end;
idx_string(str: STRING): INTEGER is
-- Assume `str' has no '%/0/' and no ['%/128/'..'%/255/']
local
utf8: INTEGER;
do
utf8 := idx_utf8(str);
from
Result := cp_up;
until
Result = 0 or else cp.item(Result).is_string_idx(utf8)
loop
Result := Result - 1;
end;
if Result = 0 then
tmp_info.clear;
tmp_info_append_u2(utf8);
add_last.set_string(tmp_info);
Result := cp_up;
end;
end;
idx_string2(str: STRING): INTEGER is
-- For all kinds of STRINGs (see idx_string)
local
i: INTEGER;
c: CHARACTER;
do
from
tmp_utf8.clear;
i := 1;
until
i > str.count
loop
c := str.item(i);
inspect
c.code
when 0 then
tmp_utf8.extend((192).to_character);
tmp_utf8.extend((128).to_character);
when 1 .. 127 then
tmp_utf8.extend(c);
when 128 .. 191 then
tmp_utf8.extend((194).to_character);
tmp_utf8.extend(c);
when 192 .. 255 then
tmp_utf8.extend((195).to_character);
tmp_utf8.extend((c.code - 64).to_character);
end;
i := i + 1;
end;
Result := idx_string(tmp_utf8);
end;
idx_name_and_type2(name, descriptor: STRING): INTEGER is
local
d: INTEGER;
do
d := idx_utf8(descriptor);
Result := idx_name_and_type1(name,d);
ensure
valid_index(Result)
end;
idx_name_and_type3(n, d: INTEGER): INTEGER is
do
from
Result := cp_up;
until
Result = 0 or else cp.item(Result).is_name_and_type_idx(n,d)
loop
Result := Result - 1;
end;
if Result = 0 then
tmp_info.clear;
tmp_info_append_u2(n);
tmp_info_append_u2(d);
add_last.set_name_and_type(tmp_info);
Result := cp_up;
end;
ensure
valid_index(Result)
end;
idx_name_and_type1(name: STRING; d: INTEGER): INTEGER is
local
n: INTEGER;
do
n := idx_utf8(name);
Result := idx_name_and_type3(n,d);
ensure
valid_index(Result)
end;
idx_name_and_type(rf: RUN_FEATURE): INTEGER is
do
Result := idx_name_and_type2(rf.name.to_key,rf.jvm_descriptor);
ensure
valid_index(Result)
end;
idx_utf8(contents: STRING): INTEGER is
do
from
Result := cp_up;
until
Result = 0 or else cp.item(Result).is_utf8_idx(contents)
loop
Result := Result - 1;
end;
if Result = 0 then
string_to_utf8(contents,tmp_info);
add_last.set_utf8(tmp_info);
Result := cp_up;
end;
ensure
valid_index(Result)
end;
feature
idx_fieldref_generating_type(c: INTEGER): INTEGER is
local
idx, nt: INTEGER;
do
idx := idx_eiffel_string_descriptor;
nt := idx_name_and_type1(as_generating_type,idx);
Result := idx_fieldref2(c,nt);
end;
idx_fieldref_generator(c: INTEGER): INTEGER is
local
idx, nt: INTEGER;
do
idx := idx_eiffel_string_descriptor;
nt := idx_name_and_type1(as_generator,idx);
Result := idx_fieldref2(c,nt);
end;
feature {PRINT_JVM_CLASS,CP_INFO}
view_in(str: STRING; idx: INTEGER) is
-- Append in `str' a human readable version.
require
valid_index(idx);
str /= Void
do
cp.item(idx).view_in(str);
end;
feature {CODE_ATTRIBUTE}
idx_eiffel_string_class: INTEGER is
do
Result := idx_class2(jvm_string_class);
end;
idx_eiffel_string_count_fieldref: INTEGER is
local
idx: INTEGER;
do
idx := idx_name_and_type2(as_count,fz_i);
Result := idx_fieldref2(idx_eiffel_string_class,idx);
end;
idx_eiffel_string_capacity_fieldref: INTEGER is
local
idx: INTEGER;
do
idx := idx_name_and_type2(as_capacity,fz_i);
Result := idx_fieldref2(idx_eiffel_string_class,idx);
end;
idx_eiffel_string_storage_fieldref: INTEGER is
local
idx: INTEGER;
do
idx := idx_name_and_type2(as_storage,fz_31);
Result := idx_fieldref2(idx_eiffel_string_class,idx);
end;
feature
idx_eiffel_string_descriptor: INTEGER is
do
Result := idx_utf8(jvm_string_descriptor);
end;
feature {NONE}
add_last: CP_INFO is
do
if cp.upper > cp_up then
cp_up := cp_up + 1;
Result := cp.item(cp_up);
else
!!Result.clear;
cp.add_last(Result);
cp_up := cp_up + 1;
end;
ensure
cp_up = 1 + old cp_up
end;
tmp_utf8: STRING is
once
!!Result.make(32);
end;
tmp_info: STRING is
once
!!Result.make(32);
end;
tmp_info_append_u2(u2: INTEGER) is
do
append_u2(tmp_info,u2);
end;
feature {NONE}
jvm_string_descriptor: STRING is
-- Descriptor for class STRING: "L<Package>/string;"
once
!!Result.make(12);
Result.extend('L');
Result.append(jvm_string_class);
Result.extend(';');
end;
jvm_string_class: STRING is
-- Fully qualified name for class STRING
once
!!Result.make(12);
Result.append(run_control.output_name);
Result.extend('/');
Result.append(fz_24);
end;
invariant
cp_up <= cp.upper;
end -- CONSTANT_POOL